<template>
  <div class="category-selector">
    <!-- 多选模式 - 用于uploads（使用el-tree，支持级联选择） -->
    <div v-if="!multiple" class="multiple-selector">
      <el-tree ref="categoryTreeRef" :data="categoryTreeData" :props="treeProps" show-checkbox node-key="id"
        default-expand-all @check="handleMultipleCheck" class="category-tree" />

      <!-- 已选分类展示 -->
      <div v-if="selectedCategories.length > 0" class="selected-categories">
        <div class="selected-title">已选分类：</div>
        <div class="category-tags">
          <el-tag v-for="category in selectedCategories" :key="category.id" type="primary" closable class="category-tag"
            @close="removeCategoryTag(category.id)">
            {{ category.categoryName }}
          </el-tag>
        </div>
      </div>
    </div>

    <!-- 多选模式 - 使用el-tree-select -->
    <el-tree-select v-else v-model="selectedIds" :data="categoryTreeData" :props="treeProps" :placeholder="placeholder"
      multiple clearable check-strictly collapse-tags collapse-tags-tooltip node-key="id" default-expand-all
      :style="{ width: width }" @change="handleMultipleTreeSelectChange" />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import { ElTree } from 'element-plus'
import { categoryList } from '@/api/fileType'

// 接口类型定义
interface Category {
  id: string
  categoryName: string
  parentId?: string | null
  children?: Category[]
}

interface SelectedCategory {
  id: string
  categoryName: string
}

// Props定义
interface Props {
  modelValue?: string | string[] // 支持单选和多选
  multiple?: boolean // 是否多选
  placeholder?: string
  width?: string
}

const props = withDefaults(defineProps<Props>(), {
  multiple: false,
  placeholder: '请选择分类',
  width: '100%'
})

// Emits定义
const emit = defineEmits<{
  'update:modelValue': [value: string | string[]]
  'change': [value: string | string[], categories?: SelectedCategory[]]
}>()

// 响应式数据
const categoryTreeRef = ref<InstanceType<typeof ElTree>>()
const categoryTreeData = ref<Category[]>([])
const selectedCategories = ref<SelectedCategory[]>([])
const selectedIds = ref<string[]>([])

// 树形结构配置
const treeProps = {
  children: 'children',
  label: 'categoryName',
  value: 'id'
}

// 单选模式的选中值
const selectedValue = computed({
  get: () => props.modelValue as string,
  set: (value: string) => {
    emit('update:modelValue', value)
  }
})

/**
 * 加载分类数据
 */
const loadCategoryData = async () => {
  try {
    const response = await categoryList()
    console.log('分类数据:', response)

    if (response.length > 0) {
      categoryTreeData.value = buildTree(response || [])
    }
  } catch (error) {
    console.error('加载分类数据失败:', error)
  }
}

/**
 * 将扁平化数据转换为树形结构
 */
const buildTree = (flatData: any[]): Category[] => {
  if (!flatData || flatData.length === 0) {
    return []
  }

  // 先处理数据格式，确保兼容性
  const processedData = flatData.map((item, index) => ({
    ...item,
    id: String(item.id) || `category_${Date.now()}_${index}`,
    categoryName: item.categoryName || item.name || '',
    parentId: item.parentId ? String(item.parentId) : null,
    children: []
  }))

  console.log('category-selector处理后的数据:', processedData)

  // 创建id到节点的映射
  const nodeMap = new Map()
  processedData.forEach(item => {
    nodeMap.set(item.id, { ...item, children: [] })
  })

  console.log('category-selector节点映射:', nodeMap)

  // 构建树形结构
  const tree: Category[] = []
  const orphanNodes: Category[] = []

  // 先添加所有顶级节点
  processedData.forEach(item => {
    const node = nodeMap.get(item.id)
    if (item.parentId === null || item.parentId === undefined || item.parentId === '') {
      tree.push(node)
    }
  })

  // 再处理子节点
  processedData.forEach(item => {
    if (item.parentId !== null && item.parentId !== undefined && item.parentId !== '') {
      const node = nodeMap.get(item.id)
      const parent = nodeMap.get(item.parentId)
      if (parent) {
        parent.children.push(node)
      } else {
        // 如果找不到父节点，记录为孤儿节点
        orphanNodes.push(node)
        console.warn(`category-selector找不到父节点 ${item.parentId}，节点 ${item.id} 将作为顶级节点处理`)
      }
    }
  })

  // 将孤儿节点添加到顶级
  tree.push(...orphanNodes)

  console.log('category-selector构建的树形结构:', tree)
  return tree
}

/**
 * 单选模式变化处理
 */
const handleSingleChange = (value: string) => {
  emit('change', value)
}

/**
 * 多选模式选择处理（el-tree-select）
 */
const handleMultipleTreeSelectChange = (value: string[]) => {
  selectedIds.value = value

  // 根据选中的ID获取分类信息
  selectedCategories.value = value.map(id => {
    const category = findCategoryById(id)
    return {
      id,
      categoryName: category?.categoryName || ''
    }
  })

  emit('update:modelValue', value)
  emit('change', value, selectedCategories.value)
}

/**
 * 根据id查找分类信息
 */
const findCategoryById = (id: string): Category | null => {
  const findInTree = (nodes: Category[]): Category | null => {
    for (const node of nodes) {
      if (node.id === id) {
        return node
      }
      if (node.children && node.children.length > 0) {
        const found = findInTree(node.children)
        if (found) return found
      }
    }
    return null
  }

  return findInTree(categoryTreeData.value)
}

/**
 * 多选模式选择处理（级联选择模式）
 */
const handleMultipleCheck = (data: Category, checked: any) => {
  // 获取所有选中的节点（包括父级和子级的级联选择）
  const checkedNodes = categoryTreeRef.value?.getCheckedNodes(false, false) as Category[]
  const halfCheckedNodes = categoryTreeRef.value?.getHalfCheckedNodes() as Category[]

  // 合并完全选中和半选中的节点，用于显示标签
  const allSelectedNodes = [...checkedNodes, ...halfCheckedNodes]
  selectedCategories.value = allSelectedNodes.map((node) => ({
    id: node.id,
    categoryName: node.categoryName
  }))

  // 传值时传递所有被勾选的节点ID（包括级联选中的父级和子级）
  // 这样选择子级时会包含父级ID，选择父级时会包含所有子级ID
  const allSelectedIds = allSelectedNodes.map(node => node.id)
  emit('update:modelValue', allSelectedIds)
  emit('change', allSelectedIds, selectedCategories.value)
}

/**
 * 移除分类标签
 */
const removeCategoryTag = (categoryId: string) => {
  // 取消树节点的选中状态（级联模式下会自动处理子节点）
  categoryTreeRef.value?.setChecked(categoryId, false, true)

  // 重新获取选中状态
  const checkedNodes = categoryTreeRef.value?.getCheckedNodes(false, false) as Category[]
  const halfCheckedNodes = categoryTreeRef.value?.getHalfCheckedNodes() as Category[]

  // 合并完全选中和半选中的节点，用于显示标签
  const allSelectedNodes = [...checkedNodes, ...halfCheckedNodes]
  selectedCategories.value = allSelectedNodes.map((node) => ({
    id: node.id,
    categoryName: node.categoryName
  }))

  // 传值时传递所有被勾选的节点ID（包括级联选中的）
  const allSelectedIds = allSelectedNodes.map(node => node.id)
  emit('update:modelValue', allSelectedIds)
  emit('change', allSelectedIds, selectedCategories.value)
}

/**
 * 根据id查找对应的节点id（用于验证节点存在性）
 */
const findNodeIdsByIds = (ids: string[]): string[] => {
  const nodeIds: string[] = []

  const findInTree = (nodes: Category[]) => {
    for (const node of nodes) {
      if (ids.includes(node.id)) {
        nodeIds.push(node.id)
      }
      if (node.children && node.children.length > 0) {
        findInTree(node.children)
      }
    }
  }

  findInTree(categoryTreeData.value)
  return nodeIds
}

/**
 * 监听modelValue变化，同步选中状态
 */
watch(
  () => props.modelValue,
  (newValue) => {
    if (props.multiple && Array.isArray(newValue)) {
      // 多选模式：同步selectedIds
      selectedIds.value = newValue

      // 更新已选分类显示
      selectedCategories.value = newValue.map(id => {
        const category = findCategoryById(id)
        return {
          id,
          categoryName: category?.categoryName || ''
        }
      })

      // 同步el-tree的选中状态
      // 等待DOM更新后设置选中状态
      if (categoryTreeRef.value && categoryTreeData.value.length > 0) {
        // 先清空所有选中状态
        categoryTreeRef.value.setCheckedKeys([], false)
        
        // 然后设置新的选中状态
        newValue.forEach(id => {
          categoryTreeRef.value?.setChecked(id, true, false) // 第三个参数为false，不使用级联模式设置
        })
      }
    }
  },
  { immediate: true }
)

/**
 * 清空选中的分类
 */
const clearSelectedCategories = () => {
  selectedCategories.value = []
  selectedIds.value = []
  
  // 清空el-tree的选中状态
  if (categoryTreeRef.value) {
    categoryTreeRef.value.setCheckedKeys([], false)
  }
  
  // 触发更新事件
  emit('update:modelValue', [])
  emit('change', [], [])
}

// 暴露方法给父组件
defineExpose({
  clearSelectedCategories
})

// 组件挂载时加载数据
onMounted(() => {
  loadCategoryData()
})
</script>

<style scoped lang="scss">
.category-selector {
  // 基础样式保持简洁，el-tree-select已有内置样式
  // width: 100%;
}

.multiple-selector {
  width: 100%;
}

.category-tree {
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 8px;
}

.selected-categories {
  margin-top: 12px;
}

.selected-title {
  font-size: 14px;
  color: #606266;
  margin-bottom: 8px;
}

.category-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.category-tag {
  margin: 0;
}
</style>